package dnl.util.lang.reflect;
import java.lang.reflect.Field;
import java.lang.reflect.Modifier;
import java.util.ArrayList;
import java.util.List;

/**
 * General reflection utility methods that are concerned with fields.
 *
 * @author Daniel Or
 * @version 1.0
 */
public class Fields {

	public static Class<?> getFieldType(Class<?> c, String propertyName){
		try {
			Field f = c.getDeclaredField(propertyName);
			return f.getType();
		} catch (SecurityException e) {
			return null;
		} catch (NoSuchFieldException e) {
			return null;
		}
	}
	
  /**
   * Gets all final static values in the given class which are of the given type.<br>
   * (if the given type is <code>Object.class</code> ALL fields will be returned.)
   * @param c the class of which all consts are desired.
   * @param type the filtering type.
   * @return a <code>List</code> containing all desired values.
   */
  public static List<?> getFinalStatics(Class<?> c, Class<?> type){
      Field[] flds = c.getFields();
      List<Object> al  = new ArrayList<Object>();

      for (int i = 0; i < flds.length; i++) {
        int mod = flds[i].getModifiers();

        if (Modifier.isPublic(mod) && Modifier.isStatic(mod) &&
            Modifier.isFinal(mod) && flds[i].getType().equals(type)) {
          try {
            al.add(flds[i].get(null));
          } catch (Exception ex) {
            ;// will not be added if exception.
          }
        }
      }

    return al;
  }
  
  public static Field[] getInstanceFields(Class<?> c){
      Field[] flds = c.getFields();
      List<Field> al  = new ArrayList<Field>();

      for (int i = 0; i < flds.length; i++) {
        int mod = flds[i].getModifiers();

        if ( !Modifier.isStatic(mod) && !Modifier.isFinal(mod) ) {
            al.add(flds[i]);
        }
      }

    return al.toArray(new Field[]{});
  }  

  /**
   *
   * @param c
   * @param name
   * @return
   */
  public static Object getStaticField(Class<?> c, String name){
      Field[] flds = c.getFields();

      for (int i = 0; i < flds.length; i++) {
        int mod = flds[i].getModifiers();

        if (Modifier.isPublic(mod) && Modifier.isStatic(mod) &&
            flds[i].getName().equals(name)) {
          try {
            return flds[i].get(null);
          } catch (Exception ex) { // improbable, were talking of a static field.
            return null;
          }
        }
      }
      return null;
  }
  
  
  

}